package org.raymond.iworks.study.performance.measure;

import org.raymond.iworks.repository.entity.TSysUser;
import org.raymond.iworks.repository.utils.RandomUser;

import java.math.BigDecimal;
import java.util.Date;
import java.util.concurrent.ThreadLocalRandom;

public class BasicMeasure {
    public static void main(String[] args) {
        BasicMeasure measure = new BasicMeasure();
        measure.testAssignNative();
    }

    public void testSystemNano(){
        long count = 100000;
        long sum = 0;
        for(int i=0; i<count; i++) {
            sum += measureSystemNano0();
        }
        System.out.println("measureSystemNano0 avg:"+sum/count); // 37
        sum = 0;
        for(int i=0; i<count; i++) {
            sum += measureSystemNano1();
        }
        System.out.println("measureSystemNano1 avg:"+sum/count); // 36
    }

    public void testAssignNative(){
        long count = 100000;
        long sum = 0;
        for(int i=0; i<count; i++) {
            sum += measureAssignBaisc();
        }
        // 考虑到System.nanoTime本身就需要耗费33~42纳秒,因此仅仅原生类型的声明赋值可以认为耗时在1ns以内
        System.out.println("measureAssignNative avg:"+sum/count); // total: 36
        sum = 0;
        for(int i=0; i<count; i++) {
            sum += measureAssignString();
        }
        System.out.println("measureAssignString avg:"+sum/count); // 66
        sum = 0;
        for(int i=0; i<count; i++) {
            sum += measureAssignInteger();
        }
        System.out.println("measureAssignInteger avg:"+sum/count); // 51
        sum = 0;
        for(int i=0; i<count; i++) {
            sum += measureAssignLong();
        }
        System.out.println("measureAssignLong avg:"+sum/count); // 132
        sum = 0;
        for(int i=0; i<count; i++) {
            sum += measureAssignBigDecimal();
        }
        System.out.println("measureAssignBigDecimal avg:"+sum/count); // 223
        sum = 0;
        for(int i=0; i<count; i++) {
            sum += measureNewUser();
        }
        System.out.println("measureNewUser avg:"+sum/count); // 56
        sum = 0;
        for(int i=0; i<count; i++) {
            sum += measureBuildRandomUser();
        }
        System.out.println("measureBuildRandomUser avg:"+sum/count); // 5微秒~9微秒
        sum = 0;
        for(int i=0; i<count; i++) {
            sum += measureRandomInt();
        }
        System.out.println("measureRandomInt avg:"+sum/count); // 40
        sum = 0;
        for(int i=0; i<count; i++) {
            sum += measureRandomLong();
        }
        System.out.println("measureRandomLong avg:"+sum/count); // 52
        sum = 0;
        for(int i=0; i<count; i++) {
            sum += measureRandomDouble();
        }
        System.out.println("measureRandomDouble avg:"+sum/count); // 49
        sum = 0;
        for(int i=0; i<count; i++) {
            sum += measureMathRandom();
        }
        System.out.println("measureMathRandom avg:"+sum/count); // 54
    }

    public long measureSystemNano0(){
        long start = System.nanoTime();
        long end = System.nanoTime();
        return end-start;
    }

    public long measureSystemNano1(){
        long start = System.nanoTime();
        return System.nanoTime()-start;
    }

    public long measureAssignBaisc(){
        long start = System.nanoTime();
        // only 1 ns follow
        long l = 10000000000l;
        int i = 10000000;
        short s = 266;
        byte b = 0x1;
        char c = 'a';
        float f = 0.000001f;
        double d = 0.00000000000002d;

        String str = "1234567890abcdefghijklmnopqrstuvwxyz";
        long end = System.nanoTime();
        return end-start;
    }

    public long measureAssignString(){
        long start = System.nanoTime();
        // cost 15~30ns
        String s = new String("1234567890abcdefghijklmnopqrstuvwxyz");
        long end = System.nanoTime();
        return end-start;
    }

    public long measureAssignInteger(){
        long start = System.nanoTime();
        // cost 1~15ns
        Integer i = 321;
        long end = System.nanoTime();
        return end-start;
    }
    public long measureAssignLong(){
        long start = System.nanoTime();
        // cost 20ns
        Long l = 987654321l;
        long end = System.nanoTime();
        return end-start;
    }
    public long measureAssignBigDecimal(){
        long start = System.nanoTime();
        // cost 100~250ns
        BigDecimal bd = new BigDecimal("123.45");
        long end = System.nanoTime();
        return end-start;
    }

    public long measureNewUser(){
        long start = System.nanoTime();
        // cost 50~60ns
        TSysUser user = new TSysUser();
        long end = System.nanoTime();
        return end-start;
    }

    public long measureBuildRandomUser(){
        long start = System.nanoTime();
        // cost 5500~8900ns
        TSysUser user = RandomUser.create("123456");
        long end = System.nanoTime();
        return end-start;
    }
    public long measureRandomInt(){
        long start = System.nanoTime();
        // cost 50~70ns
        int i = ThreadLocalRandom.current().nextInt();
        long end = System.nanoTime();
        return end-start;
    }
    public long measureRandomLong(){
        long start = System.nanoTime();
        // cost 50~70ns
        long l = ThreadLocalRandom.current().nextLong(100, 10000);
        long end = System.nanoTime();
        return end-start;
    }
    public long measureRandomDouble(){
        long start = System.nanoTime();
        // cost 50~70ns
        long l = ThreadLocalRandom.current().nextLong(100, 10000);
        long end = System.nanoTime();
        return end-start;
    }
    public long measureMathRandom(){
        long start = System.nanoTime();
        // cost 50~70ns
        double d = Math.random();
        long end = System.nanoTime();
        return end-start;
    }
}

